package com.tcu.user.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tcu.base.security.anno.NeedTokenVerify;
import com.tcu.base.utils.JwtUtil;
import com.tcu.exception.SmartException;
import com.tcu.part.entity.vo.PartVo;
import com.tcu.result.R;
import com.tcu.user.entity.Role;
import com.tcu.user.entity.User;
import com.tcu.user.entity.vo.UserVo;
import com.tcu.user.mapper.PermissionMapper;
import com.tcu.user.mapper.RoleMapper;
import com.tcu.user.service.IUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/user")
public class UserController {
    private IUserService userService;

    private RoleMapper roleMapper;

    private PermissionMapper permissionMapper;

    @Autowired
    public void setPermissionMapper(PermissionMapper permissionMapper) {
        this.permissionMapper = permissionMapper;
    }

    @Autowired
    public void setRoleMapper(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    @Autowired
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    @PostMapping("register")
    public R register(@RequestBody User user){
        User register = userService.register(user);
        return R.success().data("user",register);
    }
    @PostMapping("login")
    public R login(@RequestBody User user){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        try {
            subject.login(token);
            User principal = (User) subject.getPrincipal();
            String backToken = JwtUtil.getToken(principal.getId(), principal.getUsername());
            principal.setPassword("null");
            return R.success().data("user",principal).data("token",backToken);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            return R.error().message("该账户不存在");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            return R.error().message("密码错误");
        }

    }

    @GetMapping("token/var")
    @NeedTokenVerify
    public R tokenR(){
        return R.success();
    }


    @PostMapping("login1")
    public R login1(@RequestBody User user){
        String username = user.getUsername();
        String passwd = user.getPassword();
        if (StringUtils.hasLength(username)&&StringUtils.hasLength(passwd)) {
            return R.success().data("token", "3112311321");
        }else {
            return R.error().message("账号或密码为空");
        }

    }

    @GetMapping("checkName/{name}")
    public R checkName(@PathVariable String name){
        Boolean repeatName = userService.isRepeatName(name);
        return R.success().data("isRepeat", repeatName);
    }

    @GetMapping("logout")
    public R logout(){
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return R.success().message("登出成功");
    }

    @PostMapping("update")
    public R update(@RequestBody User user){
        if (user.getId()==null) {
            throw new SmartException(20001,"没有id，无法更新信息");
        }
        boolean b = userService.updateById(user);
        return b?R.success():R.error();
    }

    @GetMapping("getInfoById/{id}")
    public R getUserInfoById(@PathVariable String id){
        User byId = userService.getById(id);
        byId.setPassword(null);
        Set<String> roleNamesByUid = roleMapper.getRoleNamesByUid(id);
        Set<String> permissionNamesByUid = permissionMapper.getPermissionNamesByUid(id);
        return R.success().data("user",byId).data("roles",roleNamesByUid).data("permissions",permissionNamesByUid);
    }

    @DeleteMapping("delete/{id}")
    public R deleteById(@PathVariable String id){
        boolean b = userService.removeById(id);
        return b?R.success():R.error();
    }

    @PostMapping("deleteBatch")
    public R deleteBatch(@RequestBody List<String> ids){
        boolean b = userService.removeByIds(ids);
        return b?R.success():R.error();
    }

    @PostMapping("pageListCondition/{page}/{size}")
    public R pageListCondition(@PathVariable Long page, @PathVariable Long size, @RequestBody UserVo userVo){
        IPage<User> iPage =userService.pageListCondition(page,size,userVo);
        return R.success().data("pageInfo",iPage);
    }

    @PostMapping("updateUserRoles/{userId}")
    public R updateUserRoles(@PathVariable String userId,@RequestBody List<String> roles){
        Boolean flag=userService.updateUserRoles(userId,roles);
        return flag?R.success():R.error();
    }

    @GetMapping("findRolesByUid/{userId}")
    public R findRolesByUid(@PathVariable String userId){
        List<Role> rolesByUid = roleMapper.getRolesByUid(userId);
        return R.success().data("roles", rolesByUid);
    }

    @GetMapping("permissions")
    public R permissions(){
        User principal = (User) SecurityUtils.getSubject().getPrincipal();
        String userId = principal.getId();
        Set<String> permissionNamesByUid = permissionMapper.getPermissionNamesByUid(userId);
        return R.success().data("permissions", permissionNamesByUid);
    }

    @GetMapping("roles")
    public R roles(){
        User principal = (User) SecurityUtils.getSubject().getPrincipal();
        String userId = principal.getId();
        Set<String> roleNamesByUid = roleMapper.getRoleNamesByUid(userId);
        return R.success().data("roles", roleNamesByUid);
    }




}
